package com.serviceprovider.business.module.user.controller;

//~--- non-JDK imports --------------------------------------------------------

import com.serviceprovider.business.module.admin.address.model.Country;
import com.serviceprovider.business.module.admin.address.model.State;
import com.serviceprovider.business.module.admin.address.services.IGeoService;
import com.serviceprovider.business.module.admin.messages.serivces.dao.interfaces.IMessagesService;
import com.serviceprovider.business.module.admin.role.model.Role;
import com.serviceprovider.business.module.admin.role.services.dao.interfaces.IRoleService;
import com.serviceprovider.business.module.admin.settings.services.ISettingsService;
import com.serviceprovider.business.module.admin.user.services.dao.interfaces.IUserService;
import com.serviceprovider.business.module.user.model.forms.EditUserForm;
import com.serviceprovider.business.module.user.model.forms.ViewUserForm;
import com.serviceprovider.business.module.user.model.impl.User;
import com.serviceprovider.business.module.user.model.impl.UserManagerFactory;
import com.serviceprovider.business.module.user.model.interfaces.IUserManager;
import com.serviceprovider.business.utility.Int2DoublePropertyEditor;
import com.serviceprovider.business.utility.RequestConstants;
import com.serviceprovider.business.utility.maintenance.settings.RoleUtils;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

//~--- JDK imports ------------------------------------------------------------

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
 * @Leonardo A. Auer
 * @since 04/11/2011
 */

/**
 * User Controller
 * Catch all user requests.
 */
@Controller
public class UserController implements IUserManager {
    protected final Log        logger = LogFactory.getLog(getClass());
    @Autowired
    protected IGeoService      geoService;
    @Autowired
    IMessagesService           messageService;
    @Autowired
    ISettingsService           propertiesService;
    @Autowired
    IRoleService               roleService;
    @Autowired
    private UserManagerFactory userManagerFactory;
    @Autowired
    IUserService               userService;

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(Integer.class, "fee", new Int2DoublePropertyEditor(true));
    }

    @ModelAttribute("roleList")
    public List<Role> getRoleList() {
        return roleService.findAll();
    }

    @ModelAttribute("countries")
    public List<Country> getCountryList() {
        return geoService.getAllCountries();
    }

    @ModelAttribute("states")
    public List<State> getStateList() {
        return geoService.getAllStates();
    }

    @RequestMapping(value = RequestConstants.UserRequests.LOGIN)
    public ModelAndView login(HttpSession sess) {
        ModelAndView mav = new ModelAndView(RequestConstants.UserRequests.VIEW_LOGIN);

        sess.setAttribute("uiTheme", propertiesService.getUiTheme());

        return mav;
    }

    @RequestMapping(
        value  = RequestConstants.UserRequests.LOGON,
        method = RequestMethod.GET
    )
    public ModelAndView frameSetLogout() {
        return new ModelAndView(RequestConstants.UserRequests.VIEW_LOGON);
    }

    @RequestMapping(
        value  = RequestConstants.UserRequests.ADMIN_HOME,
        method = RequestMethod.GET
    )
    public ModelAndView adminHomeManagement() {
        return new ModelAndView(RequestConstants.UserRequests.VIEW_ADMIN_HOME);
    }

    @RequestMapping(
        value  = RequestConstants.UserRequests.SP_HOME,
        method = RequestMethod.GET
    )
    public ModelAndView spHomeProcedure() {
        User         provider = userService.getUserConnected();
        ModelAndView mav      = new ModelAndView(RequestConstants.UserRequests.VIEW_SP_HOME);

        mav.addObject("username", provider.getFirstName() + " " + provider.getLastName());

        return mav;
    }

    @RequestMapping(
        value  = RequestConstants.UserRequests.PROVIDER_SELECT,
        method = RequestMethod.GET
    )
    public String select(HttpSession sess) {
        User provider = userService.getUserConnected();

        sess.setAttribute("sp_id", provider.getId());
        sess.setAttribute("sp_username", provider.getFirstName() + " " + provider.getLastName());

        Role         role     = roleService.getRoleById(provider.getRole().getId());
        List<String> messages = messageService.getAllForUserRole(provider, role);

        sess.setAttribute("messages", messages);

        return role.getName().equals(RoleUtils.ROLE_ADMINISTRATOR)
               ? "redirect:" + RequestConstants.UserRequests.ADMIN_HOME
               : "redirect:" + RequestConstants.UserRequests.SP_HOME;
    }

    @RequestMapping(
        value  = RequestConstants.UserRequests.VIEW_USERS,
        method = RequestMethod.GET
    )
    public ModelAndView viewUsers(HttpServletRequest request, HttpSession session) {
        IUserManager userManager  = userManagerFactory.getManager(userManagerFactory);
        ViewUserForm viewUserForm = new ViewUserForm();

        viewUserForm.setPageNumber(1);

        return userManager.searchUsersPost(request, session, viewUserForm, null);
    }

    @RequestMapping(
        value  = RequestConstants.UserRequests.VIEW_USERS,
        method = RequestMethod.POST
    )
    public ModelAndView updateUserList(HttpServletRequest request, HttpSession session,
                                       @ModelAttribute("viewUserForm") ViewUserForm viewUserForm,
                                       BindingResult result) {
        IUserManager userManager = userManagerFactory.getManager(userManagerFactory);

        return userManager.updateUserList(request, session, viewUserForm, result);
    }

    @RequestMapping(
        value  = RequestConstants.UserRequests.SEARCH_USERS,
        method = RequestMethod.GET
    )
    public String searchUsersGet(HttpServletRequest request, HttpSession session,
                                 @ModelAttribute("viewUserForm") ViewUserForm viewUserForm, BindingResult result) {
        return "redirect:" + RequestConstants.UserRequests.VIEW_USERS;
    }

    @RequestMapping(
        value  = RequestConstants.UserRequests.SEARCH_USERS,
        method = RequestMethod.POST
    )
    public ModelAndView searchUsersPost(HttpServletRequest request, HttpSession session,
            @ModelAttribute("viewUserForm") ViewUserForm viewUserForm, BindingResult result) {
        IUserManager userManager = userManagerFactory.getManager(userManagerFactory);

        return userManager.searchUsersPost(request, session, viewUserForm, result);
    }

    @RequestMapping(
        value  = RequestConstants.UserRequests.CREATE_USER,
        method = RequestMethod.GET
    )
    public ModelAndView enterCreateUser() {
        IUserManager userManager = userManagerFactory.getManager(userManagerFactory);

        return userManager.enterCreateUser();
    }

    @RequestMapping(
        value  = RequestConstants.UserRequests.CREATE_USER,
        method = RequestMethod.POST
    )
    public ModelAndView createUser(@ModelAttribute("userForm") EditUserForm editUserForm, BindingResult result) {
        IUserManager userManager = userManagerFactory.getManager(userManagerFactory);

        return userManager.createUser(editUserForm, result);
    }

    @RequestMapping(
        value    = RequestConstants.UserRequests.VIEW_USER_DETAILS,
        method   = RequestMethod.GET
    )
    public ModelAndView viewUserDetails(@RequestParam("id") int userId, @RequestParam(
        value    = "saveSuccess",
        required = false
    ) Boolean saveSuccess) {
        IUserManager userManager = userManagerFactory.getManager(userManagerFactory);

        return userManager.viewUserDetails(userId, saveSuccess);
    }

    @RequestMapping(
        value  = RequestConstants.UserRequests.EDIT_USER_DETAILS,
        method = RequestMethod.GET
    )
    public ModelAndView editUserDetails(HttpServletRequest request) {
        IUserManager userManager = userManagerFactory.getManager(userManagerFactory);

        return userManager.editUserDetails(request);
    }

    @RequestMapping(
        value  = RequestConstants.UserRequests.EDIT_USER_DETAILS,
        method = RequestMethod.POST
    )
    public ModelAndView updateUserDetails(@ModelAttribute("userForm") EditUserForm editUserForm, BindingResult result) {
        IUserManager userManager = userManagerFactory.getManager(userManagerFactory);

        return userManager.updateUserDetails(editUserForm, result);
    }

    @RequestMapping(
        value  = RequestConstants.UserRequests.VIEW_MY_USER_DETAILS,
        method = RequestMethod.GET
    )
    public ModelAndView viewMyUserDetails() {
        IUserManager userManager = userManagerFactory.getManager(userManagerFactory);

        return userManager.viewMyUserDetails();
    }

    @RequestMapping(
        value  = RequestConstants.UserRequests.EDIT_MY_USER_DETAILS,
        method = RequestMethod.GET
    )
    public ModelAndView editMyUserDetails(HttpServletRequest request) {
        IUserManager userManager = userManagerFactory.getManager(userManagerFactory);

        return userManager.editMyUserDetails(request);
    }
}



